<template>
  <div class="map-chart">
     <my-map :zoom="5" :adapter="adapter" height="100%" :center="[106.011022, 37.237037]" @ready="readyHandle">
    <my-map-geo :json="geo" @ready="geoInit" :fill="fill" :text="text" :stroke="stroke"></my-map-geo>

    <my-map-scatter v-for="(item, index) in scatterData" :key="index" 
      :coordinate="item.pos"
      :ripple="ripple"
      :radius="item.value * 0.05" 
      fill="#F4E925"
      :delay="item.delay"
      @mouseenter="scatterHoverHandle(item)"
    ></my-map-scatter>

    <my-map-popup :position="tooltipPos" title=""  :closable="false" :offset="[0, -10]" :close-on-click="true">
       {{tooltipText}}
    </my-map-popup>
  </my-map> 
  </div>
</template>
<script>
import china from '$ui/charts/geo/china.json'
import LineString from 'ol/geom/LineString'
import View from 'ol/View';
import {areaData, geoCoordMap} from './data.js'
 
const flatCoords = function (coords, arr = []) { 
  let flag = false
  for (let index = 0; index < coords.length; index++) {
    if (coords[index][0] && typeof coords[index][0] === 'object') {
      flag = true
    }
  } 
  
  if (flag) {
    const newCoords = coords.reduce((total, item) => {
      total = total.concat(item) 
      return total
    }, [])
    flatCoords(newCoords, arr)
  } else {
    coords.forEach((coord) => {
      arr.push(coord)
    }) 
  }
  
  return arr
}
 

export default {
  components: {},
  props: {
  },
  data() {
    return {
      geo: china,
      oMap: null,
      mapComp: null,
      mapView: null,
      stroke: {
        width: 2,
        color: '#409EFF'
      },
      fill: 'rgba(0, 0, 0, 0)',
      text: {
        fill: 'white',
        font: '14px'
      }, 
      ripple: {
        // period: 1, //  动画周期，秒数
        scale: 2, // 动画中波纹的最大缩放比
        strokeColor: '#F4E925',
        strokeWidth: 2, // 边框宽度
        type: 'stroke' // 渲染类型 fill 或 stroke
      },
      areaData: areaData, 
      geoCoordMap: geoCoordMap,
      tooltipPos: null,
      tooltipText: ''
    }
  },
  computed: {
    areaDataMap() {
      return this.areaData.reduce((total, item) => {
        total[item.name] = item.value
        return total
      }, {})
    },
    scatterData() {
      return Object.entries(this.geoCoordMap).map((entry) => {
        const delay = Math.random() * 2000
        return {
          name: entry[0],
          pos: entry[1],
          value: this.areaDataMap[entry[0]],
          delay: delay
        }
      })
    }
  },
  methods: {
    adapter({TileLayer, XYZ}) {
      return new TileLayer({
        source: new XYZ({
          url: ''
        })
      })
    },
    readyHandle(map, mapComp) { 
      this.oMap = map
      this.mapComp = mapComp
      this.mapView = map.getView()
    },
    geoInit(geo) { 
      this.fixExtent(geo)

      const layer = geo.layer
       
      layer.on('postrender', evt => { // 'prerender'
        evt.context.shadowBlur = 25;
        evt.context.shadowColor = 'rgba(255,255,255,0.3)';
      }); 
    },
    fixExtent(geo) {
      const featuresCoords = geo.getFeatures().map((feature) => {
        return feature.getGeometry().getCoordinates()
      }) 
      const arr = featuresCoords.reduce((total, coords) => {
        const arr = flatCoords(coords, [])
        total = total.concat(arr)
        return total
      }, [])  
      const fullGeo = new LineString(arr)
      const extent = fullGeo.getExtent() 
      this.mapView.fit(extent, {
        padding: [40, 40, 40, 40],
        callback: () => {
          const currentCenter = this.mapView.getCenter()  
          const size = this.oMap.getSize()
          const newExtent = this.mapView.calculateExtent(size) 
          this.mapView = new View({ 
            center: currentCenter,
            zoom: 6,
            extent: newExtent
          });
          this.oMap.setView(this.mapView)
        }
      })  
    },
    scatterHoverHandle(item) {
      // console.log(item)
      this.tooltipPos = item.pos
      this.tooltipText = `${item.name}: ${item.value}`
    }
  },
  created() {
  },
  mounted() {
    console.log(this.areaDataMap, this.scatterData)
  }
}
</script>
<style lang="scss" scoped>
.map-chart{
  width:100%;
  height: 100%;
  background:#1A4876;
}
</style>